﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Agile.Engine.View;
using System.Collections;
using Agile.Engine;
using Agile.Engine.Data;
using System.Data;

namespace Fis.Win.Rules
{
    public class BillEditViewProvider : ClientViewProvider
    {

        public string Master { get; set; }
        public string Detail { get; set; }


        public override Hashtable InitializeViewModel(Hashtable args)
        {
            Hashtable m = args ?? new Hashtable();
            var mst = new Agile.Engine.Data.DataAccess() { Context = DataContext, TableName = Master };
            var dtl = new Agile.Engine.Data.DataAccess() { Context = DataContext, TableName = Detail };

            switch (ViewState)
            {
                ///新增
                case Agile.Engine.View.ViewState.AddNew:
                    var master = mst.GetNewData();
                    InitializeMasterRow(master.Rows[0], mst, m.Contains("isInitialize") ? (bool)m["isInitialize"] : false);
                    m["master"] = master;
                    m["detail"] = dtl.GetNewData(2);
                    break;
                ///修改
                case Agile.Engine.View.ViewState.Modify:
                    m["master"] = mst.GetData(m["SID"].ToString());
                    var filter = new Hashtable();
                    filter["FVCHID"] = m["SID"];

                    m["detail"] = dtl.GetData(filter);
                    (m["detail"] as DataTable).DefaultView.Sort = "SID";
                    break;
            }

            return m;
        }

        void InitializeMasterRow(System.Data.DataRow row, DataAccess da, bool isInitialize = false)
        {
            row["FBILLTYPE"] = "0";
            var sequnce = isInitialize
                ? InitSequnce()
                : BillSequnce(Fis.Win.Utils.AppSession.Book["FBOOKRANGE"].ToString());
            row["FNO"] = row["FSEQUENCE"] = sequnce;
            row["FATTACHMENT"] = 0;
        }

        public int BillSequnce(string range)
        {
            var da = new DataAccess() { Context = DataContext, TableName = Master };
            return da.Scalar(0, "MAX(FNO)", string.Format("DATEPART(month, FENTERDATE) = {0}", range)) + 1;
        }

        public int InitSequnce()
        {
            var da = new DataAccess() { Context = DataContext, TableName = Master };
            return da.Scalar(0, "MAX(FNO)", "FSTATUS = 4") + 1;
        }

        public override bool ExecuteUpdate(Hashtable viewModel)
        {
            ///验证失败
            if (!ExecuteValidate(viewModel))
            {
                return false;
            }

            ///未同步做本地修改
            var data = viewModel["master"] as DataTable;
            if (!data.Rows[0]["FSYNC"].Equals(1))
            {
                return UpdateLocal(viewModel);
            }

            var param = Fis.Win.Utils.AppSession.CreateServiceParamter(viewModel);
            param["master"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(viewModel["master"] as DataTable);
            param["detail"] = Agile.Engine.Utils.ZipUtils.ZipDataTable(viewModel["detail"] as DataTable);

            var exec = InvokeService(param);

            if (exec)
            {
                var master = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["master"].ToString());
                var detail = Agile.Engine.Utils.ZipUtils.UnZipDataTable(ServiceProcess.Result["detail"].ToString());

                DataAccess dm = new DataAccess() { Context = DataContext, TableName = Master };
                DataAccess dd = new DataAccess() { Context = DataContext, TableName = Detail };

                DataContext.DefaultModel.ExecuteTransaction(() =>
                {

                    if (ViewState == Agile.Engine.View.ViewState.AddNew)
                    {
                        dm.AddNew(master.Rows[0]);
                    }
                    else
                    {
                        dm.Update(master.Rows[0]);
                    }
                    DataContext.DefaultModel.Delete(Detail, string.Format("FVCHID='{0}'", master.Rows[0]["SID"]));
                    dd.AddNew(detail.Select());

                });

            }

            View.Message = ServiceProcess.Message;
            return exec;
        }


        public override bool UpdateLocal(Hashtable args)
        {
            var master = args["master"] as DataTable;
            var detail = args["detail"] as DataTable;

            DataAccess dm = new DataAccess() { Context = DataContext, TableName = Master };
            DataAccess dd = new DataAccess() { Context = DataContext, TableName = Detail };

            if (View.ViewState == Agile.Engine.View.ViewState.AddNew)
            {
                var guid = Guid.NewGuid().ToString();
                master.Rows[0]["SID"] = guid;
                var hashcode = guid.GetHashCode();
                var sequnce = 0;
                foreach (var i in detail.AsEnumerable())
                {
                    i["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce);
                    i["FVCHID"] = master.Rows[0]["SID"];
                }
                DataContext.DefaultModel.ExecuteTransaction(
                    () =>
                    {
                        dm.AddNew(master.Rows[0]);
                        dd.AddNew(detail.Select());
                    });
            }
            else
            {
                var hashcode = master.Rows[0]["SID"].ToString().GetHashCode();
                var sequnce = 0;
                foreach (var i in detail.AsEnumerable())
                {
                    i["SID"] = string.Format("{0}-{1:0000#}", hashcode, ++sequnce);
                    i["FVCHID"] = master.Rows[0]["SID"];
                }
                DataContext.DefaultModel.ExecuteTransaction(
                    () =>
                    {
                        
                        dm.Update(master.Rows[0]);
                        DataContext.DefaultModel.Delete(dd.TableName, string.Format("FVCHID='{0}'", master.Rows[0]["SID"]));
                        dd.AddNew(detail.Select());
                    });
            }
            return true;
        }

        public override Hashtable ExecuteQuery(object param)
        {
            var m = param as Hashtable;
            var filter = Agile.Engine.Utils.DataUtils.Parse(decimal.MaxValue, m["filter"]);
            var range = m["filter1"].ToString(); //Fis.Win.Utils.AppSession.Book["FBOOKRANGE"].ToString();
            var max = DataContext.DefaultModel.Max(Master, "FSEQUENCE", "DATEPART(month, FENTERDATE) = " + range);

            filter = (filter > max) ? max : filter;


            var sm = ObjectContext.GetResource("SqlResource").Format("billNavigateMaster", range, filter);
            var sd = ObjectContext.GetResource("SqlResource").Format("billNavigateDetail", range, filter);
            m["master"] = DataContext.DefaultModel.QueryTable(CommandType.Text, Master, sm);
            m["detail"] = DataContext.DefaultModel.QueryTable(CommandType.Text, Master, sd);

            return m;
        }

    }
}
